/*
 * 代号：凤凰
 * http://www.jphenix.org
 * 2014-06-04
 * V4.0
 */
package com.jphenix.one.h2;

import com.jphenix.kernel.baseobject.instanceb.ABase;
import com.jphenix.share.lang.SBoolean;
import com.jphenix.share.util.BaseUtil;
import com.jphenix.standard.docs.BeanInfo;
import com.jphenix.standard.docs.ClassInfo;

import java.lang.reflect.Method;
import java.util.ArrayList;

/**
 * 数据库Tcp服务管理类
 * 
 * 2019-07-15 支持自定义数据库根路径
 * 2021-03-04 增加了新的h2数据库自动创建库的参数
 * 
 * com.jphenix.one.h2.DbTcpServer
 * 
 * @author 马宝刚
 * 2009-7-28 下午02:07:55
 */
@ClassInfo({"2021-09-12 18:51","数据库Tcp服务管理类"})
@BeanInfo({"dbtcpserver"})
public class DbTcpServer extends ABase {

	/**
	 * 服务器类路径
	 */
	private final String SERVER_CLASSPATH = "org.h2.tools.Server";
	
	protected String dbPort = null; //数据库访问端口号
	protected String dbBasePath = null; //数据库文件根路径
	protected Object dbTcpServer = null; //数据库服务
	protected boolean tcpAllowOther = false; //是否其它电脑访问数据库端口
	protected boolean enabledLocalDbServer = false; //是否启用本地数据库服务
	
	/**
	 * 构造函数
	 * @author 马宝刚
	 */
	public DbTcpServer() {
		super();
	}
	
	/**
	 * 启动数据库服务
	 * 马宝刚
	 * 2009-7-28 下午02:38:09
	 * @throws Exception 执行发生异常
	 */
	public void start() throws Exception {
		if (!isEnabledLocalDbServer()) {
			return;
		}
		//构建配置参数
		ArrayList<String> argList = new ArrayList<String>();
		argList.add("-tcpPort");
		argList.add(getDbPort());
		argList.add("-baseDir");
		argList.add(getDbBasePath());
		if (isTcpAllowOther()) {
			argList.add("-tcpAllowOthers");
		}
	    //新版本的h2数据库默认不在支持自动创建库，加上这个参数就老实了
	    argList.add("-ifNotExists");
		//构建服务类
		Class<?> serverCls = Class.forName(SERVER_CLASSPATH);
		//构建服务方法
		Method cts = 
			serverCls.getDeclaredMethod(
					"createTcpServer", String[].class);
		//构建数据库TCP服务
		dbTcpServer = cts.invoke(null, BaseUtil.listToArray(argList,String.class));
		//构建启动方法
		Method startMh = 
			dbTcpServer.getClass().getMethod("start");
		log.startLog("Start DB Server: Port:["+getDbPort()+"] BasePath:["
				+getDbBasePath()+"] TcpAllowOther:["
				+(isTcpAllowOther()?"true":"false")+"]");
		//启动服务
		startMh.invoke(dbTcpServer);
	}
	
	/**
	 * 设置是否启用本地数据库服务
	 * 马宝刚
	 * 2009-7-28 下午02:43:42
	 * @param enabledLocalDbServerStr 是否启用本地数据库服务布尔字符串 yes no
	 */
	public void setEnabledLocalDbServer(String enabledLocalDbServerStr) {
		enabledLocalDbServer = 
			SBoolean.valueOf(enabledLocalDbServerStr);
	}
	
	/**
	 * 设置是否启用本地数据库服务
	 * 马宝刚
	 * 2009-7-28 下午02:43:42
	 * @param enabledLocalDbServer 是否启用本地数据库服务
	 */
	public void setEnabledLocalDbServer(boolean enabledLocalDbServer) {
		this.enabledLocalDbServer = enabledLocalDbServer;
	}
	
	/**
	 * 是否启用本地数据库服务
	 * 马宝刚
	 * 2009-7-28 下午02:45:03
	 * @return 是否启用本地数据库服务
	 */
	public boolean isEnabledLocalDbServer() {
		return enabledLocalDbServer;
	}
	
	/**
	 * 停止数据库服务
	 * 马宝刚
	 * 2009-7-28 下午02:38:31
	 */
	public void stop(){
		if (dbTcpServer==null) {
			return;
		}
		try {
			//构建终止方法
			Method shutdownMh = 
				dbTcpServer.getClass().getMethod("stop");
			//执行终止
			shutdownMh.invoke(dbTcpServer);
		}catch(Exception e) {}
	}
	
	/**
	 * 设置数据库访问端口号
	 * 马宝刚
	 * 2009-7-28 下午02:33:50
	 * @param dbPort 数据库访问端口号
	 */
	public void setDbPort(String dbPort) {
		this.dbPort = dbPort;
	}
	
	/**
	 * 获取数据库访问端口号
	 * 马宝刚
	 * 2009-7-28 下午02:34:03
	 * @return 数据库访问端口号
	 */
	public String getDbPort() {
		if(dbPort==null) {
			dbPort = "8348";
		}
		return dbPort;
	}
	
	
	/**
	 * 获取数据库文件根路径
	 * 马宝刚
	 * 2009-7-28 下午02:35:45
	 * @param dbBasePath 数据库文件根路径
	 */
	public void setDbBasePath(String dbBasePath) {
		this.dbBasePath = infPath(p("file_sources")+dbBasePath);
	}
	
	
	/**
	 * 设置数据库文件根路径
	 * 马宝刚
	 * 2009-7-28 下午02:35:56
	 * @return 数据库文件根路径
	 */
	public String getDbBasePath() {
		if (dbBasePath==null) {
			dbBasePath = infPath(p("file_sources")+"/db");
		}
		return dbBasePath;
	}

	/**
	 * 是否其它电脑访问数据库端口
	 * 马宝刚
	 * 2009-7-28 下午04:09:16
	 * @return 是否其它电脑访问数据库端口
	 */
	public boolean isTcpAllowOther() {
		return tcpAllowOther;
	}
	
	/**
	 * 设置是否其它电脑访问数据库端口
	 * 马宝刚
	 * 2009-7-28 下午04:09:25
	 * @param tcpAllowOther 是否其它电脑访问数据库端口
	 */
	public void setTcpAllowOther(boolean tcpAllowOther) {
		this.tcpAllowOther = tcpAllowOther;
	}
	
	/**
	 * 设置是否其它电脑访问数据库端口
	 * 马宝刚
	 * 2009-7-28 下午04:09:25
	 * @param tcpAllowOtherStr 是否其它电脑访问数据库端口
	 */
	public void setTcpAllowOther(String tcpAllowOtherStr) {
		tcpAllowOther = SBoolean.valueOf(tcpAllowOtherStr);
	}
}
